package com.zjj.shiro.config;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zjj.shiro.MyShiroRealm;
import com.zjj.shiro.permission.MyCustomPermissionResolver;
import com.zjj.shiro.service.ShiroService;

/**
 * 
 * @author zjj
 */
@Configuration
public class ShiroConfig {
	
	@Autowired
	private ShiroService shiroService;
	
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);

		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
		// 过滤链定义，从上向下顺序执行 authc:必须认证通过才可以访问; anon:可以匿名访问
		filterChainDefinitionMap.put("/static/**", "anon");
		filterChainDefinitionMap.put("/login", "anon");
		// 加入需要进行授权的资源权限
		List<Map<String, Object>> allResrouceList = shiroService.queryAllResource("0");
		if (CollectionUtils.isNotEmpty(allResrouceList)) {
			for (Map<String, Object> map : allResrouceList) {
				String url = (String) map.get("URL");
				String value = "perms[" + map.get("VALUE") + "]";
				filterChainDefinitionMap.put(url, value);
			}
		}
		filterChainDefinitionMap.put("/**", "authc");
		
		// 如果不设置默认自动寻找Web工程根目录下的"/login.jsp"页面
		shiroFilterFactoryBean.setLoginUrl("/login");
		// 登录成功跳转
		// shiroFilterFactoryBean.setSuccessUrl("/index");

		// 未授权界面;
		shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}
	
	@Bean
	public MyShiroRealm myShiroRealm() {
		MyShiroRealm myShiroRealm = new MyShiroRealm();
		return myShiroRealm;
	}
	
	@Bean
	public MyCustomPermissionResolver myCustomPermissionResolver() {
		MyCustomPermissionResolver myCustomPermissionResolver = new MyCustomPermissionResolver();
		return myCustomPermissionResolver;
	}
	
	@Bean 
	public ModularRealmAuthorizer modularRealmAuthorizer() {
		ModularRealmAuthorizer modularRealmAuthorizer = new ModularRealmAuthorizer();
		modularRealmAuthorizer.setPermissionResolver(myCustomPermissionResolver());
		return modularRealmAuthorizer;
	}
	
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setAuthorizer(modularRealmAuthorizer());
		securityManager.setRealm(myShiroRealm());
		return securityManager;
	}
	
   /**
     * 开启shiro aop注解支持.
     * 使用代理方式;所以需要开启代码支持;
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

